<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <!-- hexo-inject:begin --><!-- hexo-inject:end --><meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"yao_yu.gitee.io","root":"/","scheme":"Muse","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="CMake教程小结[toc] 简介CMake教程通过一个示例项目, 逐步介绍了CMake构建系统的主要功能, 包括:  生成执行程序 生成库(使用旧式CMake宏定义方法) 生成库(使用新式CMake宏定义方法–使用要求) 基于源代码的安装与测试 系统检测 添加自定义命令以及生成文件 构建安装程序 将测试结果提交到Kitware的公共指示板 混合静态和共享(动态)库 生成器表达式,条件判断 fin">
<meta property="og:type" content="article">
<meta property="og:title" content="CMake教程小结">
<meta property="og:url" content="https://yao_yu.gitee.io/2020/05/11/CMake%E6%95%99%E7%A8%8B%E5%B0%8F%E7%BB%93/index.html">
<meta property="og:site_name" content="大师之路">
<meta property="og:description" content="CMake教程小结[toc] 简介CMake教程通过一个示例项目, 逐步介绍了CMake构建系统的主要功能, 包括:  生成执行程序 生成库(使用旧式CMake宏定义方法) 生成库(使用新式CMake宏定义方法–使用要求) 基于源代码的安装与测试 系统检测 添加自定义命令以及生成文件 构建安装程序 将测试结果提交到Kitware的公共指示板 混合静态和共享(动态)库 生成器表达式,条件判断 fin">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2020-05-11T09:36:01.210Z">
<meta property="article:modified_time" content="2020-05-09T08:59:58.495Z">
<meta property="article:author" content="老树">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="https://yao_yu.gitee.io/2020/05/11/CMake%E6%95%99%E7%A8%8B%E5%B0%8F%E7%BB%93/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>CMake教程小结 | 大师之路</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript><!-- hexo-inject:begin --><!-- hexo-inject:end -->

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <!-- hexo-inject:begin --><!-- hexo-inject:end --><div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">大师之路</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://yao_yu.gitee.io/2020/05/11/CMake%E6%95%99%E7%A8%8B%E5%B0%8F%E7%BB%93/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="老树">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="大师之路">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          CMake教程小结
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-05-11 17:36:01" itemprop="dateCreated datePublished" datetime="2020-05-11T17:36:01+08:00">2020-05-11</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2020-05-09 16:59:58" itemprop="dateModified" datetime="2020-05-09T16:59:58+08:00">2020-05-09</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="CMake教程小结"><a href="#CMake教程小结" class="headerlink" title="CMake教程小结"></a>CMake教程小结</h1><p>[toc]</p>
<h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p>CMake教程通过一个示例项目, 逐步介绍了CMake构建系统的主要功能, 包括:</p>
<ol>
<li>生成执行程序</li>
<li>生成库(使用旧式CMake宏定义方法)</li>
<li>生成库(使用新式CMake宏定义方法–使用要求)</li>
<li>基于源代码的安装与测试</li>
<li>系统检测</li>
<li>添加自定义命令以及生成文件</li>
<li>构建安装程序</li>
<li>将测试结果提交到Kitware的公共指示板</li>
<li>混合静态和共享(动态)库</li>
<li>生成器表达式,条件判断</li>
<li><a href="https://cmake.org/cmake/help/latest/command/find_package.html#command:find_package" target="_blank" rel="noopener">find_package()</a>支持(添加导出配置)</li>
<li>将调试版和发行版打包在一起(win10试验没有成功)</li>
</ol>
<blockquote>
<p>注:</p>
<ol>
<li>示例项目目录在CMake源代码树的<code>Help\guide\tutorial</code>目录</li>
<li>本摘要主要关注CMake使用, 一些关于源代码的更改在请查看<a href="https://cmake.org/cmake/help/latest/guide/tutorial/index.html" target="_blank" rel="noopener">CMake教程</a></li>
<li>CMake教程示例代码,下一步的内容都是上一步的结果</li>
</ol>
</blockquote>
<h2 id="主要功能摘要"><a href="#主要功能摘要" class="headerlink" title="主要功能摘要"></a>主要功能摘要</h2><h3 id="1-生成执行程序"><a href="#1-生成执行程序" class="headerlink" title="1. 生成执行程序"></a>1. 生成执行程序</h3><p>本节示例展示了:</p>
<ul>
<li>生成执行程序的基本构建系统框架;</li>
<li>将一些CMake属性通过配置文件输出;</li>
<li>如何在目标中添加头文件搜索路径;</li>
<li>常规CMake命令行使用方式</li>
</ul>
<blockquote>
<p>注: 本节示例初始代码在示例目录的<code>Step1</code>子目录, 成果在<code>Step2</code>子目录</p>
</blockquote>
<h4 id="核心代码"><a href="#核心代码" class="headerlink" title="核心代码"></a>核心代码</h4><p>顶层目录的<strong>CMakeLists.txt</strong>内容如下:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 指定CMake最小版本</span></span><br><span class="line"><span class="keyword">cmake_minimum_required</span>(VERSION <span class="number">3.10</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置项目名称及版本号</span></span><br><span class="line"><span class="keyword">project</span>(Tutorial VERSION <span class="number">1.0</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 指定C++版本</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD <span class="number">11</span>)</span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD_REQUIRED <span class="keyword">True</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置头文件, 将一些CMake属性值保存到源代码中</span></span><br><span class="line"><span class="keyword">configure_file</span>(TutorialConfig.h.in TutorialConfig.h)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成执行程序</span></span><br><span class="line"><span class="keyword">add_executable</span>(Tutorial tutorial.cxx)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 将项目输出目录(binary tree)添加到Tutorial目标的头文件搜索路径, 这样才能找到生成的TutorialConfig.h</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(Tutorial PUBLIC</span><br><span class="line">                           <span class="string">"$&#123;PROJECT_BINARY_DIR&#125;"</span></span><br><span class="line">                           )</span><br></pre></td></tr></table></figure>

<p><strong>TutorialConfig.h.in</strong>内容如下:</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 接受CMake配置属性</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@</span></span><br></pre></td></tr></table></figure>

<h4 id="命令行使用示例"><a href="#命令行使用示例" class="headerlink" title="命令行使用示例"></a>命令行使用示例</h4><p>在项目目录下</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir build</span><br><span class="line">$ cd build</span><br><span class="line">$ cmake ..</span><br><span class="line">$ cmake --build .</span><br></pre></td></tr></table></figure>

<h3 id="2-生成库-旧式CMake"><a href="#2-生成库-旧式CMake" class="headerlink" title="2. 生成库(旧式CMake)"></a>2. 生成库(旧式CMake)</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>生成库;</li>
<li>在项目中添加库;</li>
<li>使用可选项,并将可选项保存到配置文件中;</li>
<li>目标链接库的旧式方法;</li>
<li>目标包含库头文件目录的旧式方法;</li>
</ul>
<blockquote>
<p>注: 本节示例初始代码在示例目录的<code>Step2</code>子目录, 成果在<code>Step3</code>子目录</p>
</blockquote>
<h4 id="生成库"><a href="#生成库" class="headerlink" title="生成库"></a>生成库</h4><ol>
<li>创建库目录;</li>
<li>在库目录<strong>CMakeLists.txt</strong>中, 添加生成库命令如下:</li>
</ol>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 生成库</span></span><br><span class="line"><span class="keyword">add_library</span>(MathFunctions mysqrt.cxx)</span><br></pre></td></tr></table></figure>

<h4 id="其它核心代码"><a href="#其它核心代码" class="headerlink" title="其它核心代码"></a>其它核心代码</h4><p>项目<strong>CMakeLists.txt</strong>内容如下:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 指定CMake最小版本</span></span><br><span class="line"><span class="keyword">cmake_minimum_required</span>(VERSION <span class="number">3.10</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置项目名称及版本号</span></span><br><span class="line"><span class="keyword">project</span>(Tutorial VERSION <span class="number">1.0</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 指定C++版本</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD <span class="number">11</span>)</span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD_REQUIRED <span class="keyword">True</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否使用自定义数学库可选项</span></span><br><span class="line"><span class="keyword">option</span>(USE_MYMATH <span class="string">"Use tutorial provided math implementation"</span> <span class="keyword">ON</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置头文件, 将一些CMake属性值保存到源代码中</span></span><br><span class="line"><span class="keyword">configure_file</span>(TutorialConfig.h.in TutorialConfig.h)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加自定义数学库</span></span><br><span class="line"><span class="keyword">if</span>(USE_MYMATH)</span><br><span class="line">  <span class="keyword">add_subdirectory</span>(MathFunctions)</span><br><span class="line">  <span class="keyword">list</span>(APPEND EXTRA_LIBS MathFunctions)</span><br><span class="line">  <span class="keyword">list</span>(APPEND EXTRA_INCLUDES <span class="string">"$&#123;PROJECT_SOURCE_DIR&#125;/MathFunctions"</span>)</span><br><span class="line"><span class="keyword">endif</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成执行程序</span></span><br><span class="line"><span class="keyword">add_executable</span>(Tutorial tutorial.cxx)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Tutorial目标链接相关库</span></span><br><span class="line"><span class="keyword">target_link_libraries</span>(Tutorial PUBLIC <span class="variable">$&#123;EXTRA_LIBS&#125;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Tutorial目标添加头文件搜索路径(项目生成目录,其它头文件目录)</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(Tutorial PUBLIC</span><br><span class="line">                           <span class="string">"$&#123;PROJECT_BINARY_DIR&#125;"</span></span><br><span class="line">                           <span class="variable">$&#123;EXTRA_INCLUDES&#125;</span></span><br><span class="line">                           )</span><br></pre></td></tr></table></figure>

<p><strong>TutorialConfig.h.in</strong>内容如下:</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 接受CMake配置属性</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@</span></span><br><span class="line"><span class="meta">#cmakedefine USE_MYMATH</span></span><br></pre></td></tr></table></figure>

<h3 id="3-生成库-新式CMake"><a href="#3-生成库-新式CMake" class="headerlink" title="3. 生成库(新式CMake)"></a>3. 生成库(新式CMake)</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>在库中使用<strong>INTERFACE</strong>;</li>
<li>在项目中添加库;</li>
<li>使用可选项,并将可选项保存到配置文件中;</li>
<li>目标链接库的旧式方法;</li>
<li>目标包含库头文件目录的旧式方法;</li>
</ul>
<blockquote>
<p>注: 本节示例初始代码在示例目录的<code>Step3</code>子目录, 成果在<code>Step4</code>子目录</p>
</blockquote>
<h4 id="核心代码更改"><a href="#核心代码更改" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p><strong>库目录CMakeLists.txt</strong>内容如下:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 生成库</span></span><br><span class="line"><span class="keyword">add_library</span>(MathFunctions mysqrt.cxx)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置目录头文件搜索路径. INTERFACE是使用者需要, 库本身不需要</span></span><br><span class="line"><span class="comment"># 通过INTERFACE可以将头文件搜索路径转递给使用者</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(MathFunctions</span><br><span class="line">          INTERFACE <span class="variable">$&#123;CMAKE_CURRENT_SOURCE_DIR&#125;</span></span><br><span class="line">          )</span><br></pre></td></tr></table></figure>

<p><strong>项目CMakeLists.txt</strong>删除了<em>EXTRA_INCLUDES</em>相关代码, 变化如下:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 指定CMake最小版本</span></span><br><span class="line"><span class="keyword">cmake_minimum_required</span>(VERSION <span class="number">3.10</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置项目名称及版本号</span></span><br><span class="line"><span class="keyword">project</span>(Tutorial VERSION <span class="number">1.0</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 指定C++版本</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD <span class="number">11</span>)</span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD_REQUIRED <span class="keyword">True</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否使用自定义数学库可选项</span></span><br><span class="line"><span class="keyword">option</span>(USE_MYMATH <span class="string">"Use tutorial provided math implementation"</span> <span class="keyword">ON</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置头文件, 将一些CMake属性值保存到源代码中</span></span><br><span class="line"><span class="keyword">configure_file</span>(TutorialConfig.h.in TutorialConfig.h)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加自定义数学库</span></span><br><span class="line"><span class="keyword">if</span>(USE_MYMATH)</span><br><span class="line">  <span class="keyword">add_subdirectory</span>(MathFunctions)</span><br><span class="line">  <span class="keyword">list</span>(APPEND EXTRA_LIBS MathFunctions)</span><br><span class="line"><span class="keyword">endif</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成执行程序</span></span><br><span class="line"><span class="keyword">add_executable</span>(Tutorial tutorial.cxx)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Tutorial目标链接相关库(此代码会使用新式CMake方法传递库属性)</span></span><br><span class="line"><span class="keyword">target_link_libraries</span>(Tutorial PUBLIC <span class="variable">$&#123;EXTRA_LIBS&#125;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Tutorial目标添加头文件搜索路径</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(Tutorial PUBLIC</span><br><span class="line">                           <span class="string">"$&#123;PROJECT_BINARY_DIR&#125;"</span></span><br><span class="line">                           )</span><br></pre></td></tr></table></figure>

<h3 id="4-基于源代码的安装与测试"><a href="#4-基于源代码的安装与测试" class="headerlink" title="4. 基于源代码的安装与测试"></a>4. 基于源代码的安装与测试</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>使用基于源代码的安装规则(install);</li>
<li>使用测试;</li>
</ul>
<blockquote>
<p>注: 本节示例初始代码在示例目录的<code>Step4</code>子目录, 成果在<code>Step5</code>子目录</p>
</blockquote>
<h4 id="核心代码更改-1"><a href="#核心代码更改-1" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p><strong>库目录CMakeLists.txt</strong>变化如下:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 生成库</span></span><br><span class="line"><span class="keyword">add_library</span>(MathFunctions mysqrt.cxx)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置目录头文件搜索路径. INTERFACE是使用者需要, 库本身不需要</span></span><br><span class="line"><span class="comment"># 通过INTERFACE可以将头文件搜索路径转递给使用者</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(MathFunctions</span><br><span class="line">          INTERFACE <span class="variable">$&#123;CMAKE_CURRENT_SOURCE_DIR&#125;</span></span><br><span class="line">          )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装规则</span></span><br><span class="line"><span class="keyword">install</span>(TARGETS MathFunctions DESTINATION lib)</span><br><span class="line"><span class="keyword">install</span>(FILES MathFunctions.h DESTINATION <span class="keyword">include</span>)</span><br></pre></td></tr></table></figure>

<p><strong>项目CMakeLists.txt</strong>新增了安装与测试相关代码, 变化如下:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 指定CMake最小版本</span></span><br><span class="line"><span class="keyword">cmake_minimum_required</span>(VERSION <span class="number">3.10</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置项目名称及版本号</span></span><br><span class="line"><span class="keyword">project</span>(Tutorial VERSION <span class="number">1.0</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 指定C++版本</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD <span class="number">11</span>)</span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD_REQUIRED <span class="keyword">True</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否使用自定义数学库可选项</span></span><br><span class="line"><span class="keyword">option</span>(USE_MYMATH <span class="string">"Use tutorial provided math implementation"</span> <span class="keyword">ON</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置头文件, 将一些CMake属性值保存到源代码中</span></span><br><span class="line"><span class="keyword">configure_file</span>(TutorialConfig.h.in TutorialConfig.h)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加自定义数学库</span></span><br><span class="line"><span class="keyword">if</span>(USE_MYMATH)</span><br><span class="line">  <span class="keyword">add_subdirectory</span>(MathFunctions)</span><br><span class="line">  <span class="keyword">list</span>(APPEND EXTRA_LIBS MathFunctions)</span><br><span class="line"><span class="keyword">endif</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成执行程序</span></span><br><span class="line"><span class="keyword">add_executable</span>(Tutorial tutorial.cxx)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Tutorial目标链接相关库(此代码会使用新式CMake方法传递库属性)</span></span><br><span class="line"><span class="keyword">target_link_libraries</span>(Tutorial PUBLIC <span class="variable">$&#123;EXTRA_LIBS&#125;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Tutorial目标添加头文件搜索路径</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(Tutorial PUBLIC</span><br><span class="line">                           <span class="string">"$&#123;PROJECT_BINARY_DIR&#125;"</span></span><br><span class="line">                           )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加安装目标</span></span><br><span class="line"><span class="keyword">install</span>(TARGETS Tutorial DESTINATION bin)</span><br><span class="line"><span class="keyword">install</span>(FILES <span class="string">"$&#123;PROJECT_BINARY_DIR&#125;/TutorialConfig.h"</span></span><br><span class="line">  DESTINATION <span class="keyword">include</span></span><br><span class="line">  )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 开启测试</span></span><br><span class="line"><span class="keyword">enable_testing</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 验证Tutorial正常运行</span></span><br><span class="line"><span class="keyword">add_test</span>(NAME Runs <span class="keyword">COMMAND</span> Tutorial <span class="number">25</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 验证Tutorial的使用方法提示</span></span><br><span class="line"><span class="keyword">add_test</span>(NAME Usage <span class="keyword">COMMAND</span> Tutorial)</span><br><span class="line"><span class="keyword">set_tests_properties</span>(Usage</span><br><span class="line">  PROPERTIES PASS_REGULAR_EXPRESSION <span class="string">"Usage:.*number"</span></span><br><span class="line">  )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义函数以简化测试添加</span></span><br><span class="line"><span class="keyword">function</span>(do_test <span class="keyword">target</span> arg result)</span><br><span class="line">  <span class="keyword">add_test</span>(NAME Comp<span class="variable">$&#123;arg&#125;</span> <span class="keyword">COMMAND</span> <span class="variable">$&#123;target&#125;</span> <span class="variable">$&#123;arg&#125;</span>)</span><br><span class="line">  <span class="keyword">set_tests_properties</span>(Comp<span class="variable">$&#123;arg&#125;</span></span><br><span class="line">    PROPERTIES PASS_REGULAR_EXPRESSION <span class="variable">$&#123;result&#125;</span></span><br><span class="line">    )</span><br><span class="line"><span class="keyword">endfunction</span>(do_test)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 批量添加基于结果的测试</span></span><br><span class="line">do_test(Tutorial <span class="number">4</span> <span class="string">"4 is 2"</span>)</span><br><span class="line">do_test(Tutorial <span class="number">9</span> <span class="string">"9 is 3"</span>)</span><br><span class="line">do_test(Tutorial <span class="number">5</span> <span class="string">"5 is 2.236"</span>)</span><br><span class="line">do_test(Tutorial <span class="number">7</span> <span class="string">"7 is 2.645"</span>)</span><br><span class="line">do_test(Tutorial <span class="number">25</span> <span class="string">"25 is 5"</span>)</span><br><span class="line">do_test(Tutorial -<span class="number">25</span> <span class="string">"-25 is [-nan|nan|0]"</span>)</span><br><span class="line">do_test(Tutorial <span class="number">0.0001</span> <span class="string">"0.0001 is 0.01"</span>)</span><br></pre></td></tr></table></figure>

<h4 id="命令行使用示例-1"><a href="#命令行使用示例-1" class="headerlink" title="命令行使用示例"></a>命令行使用示例</h4><p>将调试版<strong>安装</strong>到<em>D:\Temp2\ttt\debug</em></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir build</span><br><span class="line">$ cd build</span><br><span class="line">$ cmake ..</span><br><span class="line">生成并安装调试版</span><br><span class="line">$ cmake --build .</span><br><span class="line">$ cmake --install . --prefix D:\Temp2\ttt\debug --config Debug</span><br><span class="line">生成并安装发行版</span><br><span class="line">$ cmake --build . -- config Release</span><br><span class="line">$ cmake --install . --prefix D:\Temp2\ttt\Release --config Release</span><br></pre></td></tr></table></figure>

<p><strong>win10 VS2019 测试</strong></p>
<p>在<strong>build</strong>目录测试应用程序</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir build</span><br><span class="line">$ cd build</span><br><span class="line">$ cmake ..</span><br><span class="line">生成并测试调试版</span><br><span class="line">$ cmake --build .</span><br><span class="line">$ ctest -C Debug [-vv]</span><br><span class="line">生成并测试发行版</span><br><span class="line">$ cmake --build . -- config Release</span><br><span class="line">$ ctest -C Release [-vv]</span><br></pre></td></tr></table></figure>


<h3 id="5-系统检测"><a href="#5-系统检测" class="headerlink" title="5. 系统检测"></a>5. 系统检测</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>CMake系统功能检测, 以判断平台是否支持特定功能;</li>
<li>目标编译定义(宏定义);</li>
</ul>
<blockquote>
<p>注1: 本节示例初始代码在示例目录的<code>Step5</code>子目录, 成果在<code>Step6</code>子目录<br>注2: 在win10下测试失败, 没有发现log,exp函数</p>
</blockquote>
<h4 id="核心代码更改-2"><a href="#核心代码更改-2" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p><strong>库目录CMakeLists.txt</strong>变化如下:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 生成库</span></span><br><span class="line"><span class="keyword">add_library</span>(MathFunctions mysqrt.cxx)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置目录头文件搜索路径. INTERFACE是使用者需要, 库本身不需要</span></span><br><span class="line"><span class="comment"># 通过INTERFACE可以将头文件搜索路径转递给使用者</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(MathFunctions</span><br><span class="line">          INTERFACE <span class="variable">$&#123;CMAKE_CURRENT_SOURCE_DIR&#125;</span></span><br><span class="line">          )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 检测系统是否支持log,exp函数?</span></span><br><span class="line"><span class="keyword">include</span>(CheckSymbolExists)</span><br><span class="line"><span class="keyword">set</span>(CMAKE_REQUIRED_LIBRARIES <span class="string">"m"</span>)</span><br><span class="line">check_symbol_exists(log <span class="string">"math.h"</span> HAVE_LOG)</span><br><span class="line">check_symbol_exists(exp <span class="string">"math.h"</span> HAVE_EXP)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(HAVE_LOG <span class="keyword">AND</span> HAVE_EXP)</span><br><span class="line">  <span class="comment"># 目标宏定义</span></span><br><span class="line">  <span class="keyword">target_compile_definitions</span>(MathFunctions</span><br><span class="line">                             PRIVATE <span class="string">"HAVE_LOG"</span> <span class="string">"HAVE_EXP"</span>)</span><br><span class="line"><span class="keyword">endif</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装规则</span></span><br><span class="line"><span class="keyword">install</span>(TARGETS MathFunctions DESTINATION lib)</span><br><span class="line"><span class="keyword">install</span>(FILES MathFunctions.h DESTINATION <span class="keyword">include</span>)</span><br></pre></td></tr></table></figure>

<h3 id="6-添加自定义命令以及生成文件"><a href="#6-添加自定义命令以及生成文件" class="headerlink" title="6. 添加自定义命令以及生成文件"></a>6. 添加自定义命令以及生成文件</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>CMake使用命令;</li>
<li>使用生成文件;</li>
</ul>
<blockquote>
<p>注: 本节示例初始代码在示例目录的<code>Step6</code>子目录, 成果在<code>Step7</code>子目录</p>
</blockquote>
<h4 id="核心代码更改-3"><a href="#核心代码更改-3" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p><strong>库目录CMakeLists.txt</strong>变化如下:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 首先生成一个用于产生预定义值表源代码的执行程序</span></span><br><span class="line"><span class="keyword">add_executable</span>(MakeTable MakeTable.cxx)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加自定义命令以产生源代码(依赖于MakeTable目标)</span></span><br><span class="line"><span class="keyword">add_custom_command</span>(</span><br><span class="line">  OUTPUT <span class="variable">$&#123;CMAKE_CURRENT_BINARY_DIR&#125;</span>/Table.h</span><br><span class="line">  <span class="keyword">COMMAND</span> MakeTable <span class="variable">$&#123;CMAKE_CURRENT_BINARY_DIR&#125;</span>/Table.h</span><br><span class="line">  DEPENDS MakeTable</span><br><span class="line">  )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成主库(包含上一步中生成的预定义值表源代码)</span></span><br><span class="line"><span class="keyword">add_library</span>(MathFunctions</span><br><span class="line">            mysqrt.cxx</span><br><span class="line">            <span class="variable">$&#123;CMAKE_CURRENT_BINARY_DIR&#125;</span>/Table.h</span><br><span class="line">            )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通过INTERFACE向使用者传播头文件搜索路径</span></span><br><span class="line"><span class="comment"># 通过PRIVATE定义目标内部使用头文件搜索路径</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(MathFunctions</span><br><span class="line">          INTERFACE <span class="variable">$&#123;CMAKE_CURRENT_SOURCE_DIR&#125;</span></span><br><span class="line">          PRIVATE <span class="variable">$&#123;CMAKE_CURRENT_BINARY_DIR&#125;</span></span><br><span class="line">          )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装规则</span></span><br><span class="line"><span class="keyword">install</span>(TARGETS MathFunctions DESTINATION lib)</span><br><span class="line"><span class="keyword">install</span>(FILES MathFunctions.h DESTINATION <span class="keyword">include</span>)</span><br></pre></td></tr></table></figure>


<h3 id="7-构建安装程序"><a href="#7-构建安装程序" class="headerlink" title="7. 构建安装程序"></a>7. 构建安装程序</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>制作安装包;</li>
</ul>
<blockquote>
<p>注1: 本节示例初始代码在示例目录的<code>Step7</code>子目录, 成果在<code>Step8</code>子目录<br>注2: 为测试需要, 在win10上, 首先安装NSIS(Nulsoft Install System).</p>
</blockquote>
<h4 id="核心代码更改-4"><a href="#核心代码更改-4" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p><strong>顶层目录CMakeLists.txt</strong>末尾添加如下内容即可:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 设置安装器</span></span><br><span class="line"><span class="keyword">include</span>(InstallRequiredSystemLibraries)</span><br><span class="line"><span class="keyword">set</span>(CPACK_RESOURCE_FILE_LICENSE <span class="string">"$&#123;CMAKE_CURRENT_SOURCE_DIR&#125;/License.txt"</span>)</span><br><span class="line"><span class="keyword">set</span>(CPACK_PACKAGE_VERSION_MAJOR <span class="string">"$&#123;Tutorial_VERSION_MAJOR&#125;"</span>)</span><br><span class="line"><span class="keyword">set</span>(CPACK_PACKAGE_VERSION_MINOR <span class="string">"$&#123;Tutorial_VERSION_MINOR&#125;"</span>)</span><br><span class="line"><span class="keyword">include</span>(CPack)</span><br></pre></td></tr></table></figure>

<h4 id="命令行使用示例-2"><a href="#命令行使用示例-2" class="headerlink" title="命令行使用示例"></a>命令行使用示例</h4><p>在项目目录下</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir build</span><br><span class="line">$ cd build</span><br><span class="line">$ cmake ..</span><br><span class="line">$ cmake --build .</span><br><span class="line">VS generator 注意：目录不能含有中文</span><br><span class="line">生成发行版安装包(Tutorial-1.0-win64.exe)</span><br><span class="line">$ cmake --build . --target PACKAGE --config Release</span><br><span class="line">生成调试版安装包(Tutorial-1.0-win64.exe)</span><br><span class="line">$ cmake --build . --target PACKAGE --config Debug</span><br></pre></td></tr></table></figure>


<h3 id="8-将测试结果提交到Kitware的公共指示板"><a href="#8-将测试结果提交到Kitware的公共指示板" class="headerlink" title="8. 将测试结果提交到Kitware的公共指示板"></a>8. 将测试结果提交到Kitware的公共指示板</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>将测试结果提交到Kitware的公共指示板;</li>
</ul>
<blockquote>
<p>注: 本节示例初始代码在示例目录的<code>Step8</code>子目录, 成果在<code>Step9</code>子目录</p>
</blockquote>
<h4 id="核心代码更改-5"><a href="#核心代码更改-5" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p><strong>顶层目录CMakeLists.txt</strong>将:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># enable testing</span></span><br><span class="line"><span class="keyword">enable_testing</span>()</span><br></pre></td></tr></table></figure>

<p>替换为:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># enable dashboard scripting</span></span><br><span class="line"><span class="keyword">include</span>(CTest)</span><br></pre></td></tr></table></figure>

<p>在顶层目录创建<strong>CTestConfig.cmake</strong>:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">set</span>(CTEST_PROJECT_NAME <span class="string">"CMakeTutorial"</span>)</span><br><span class="line"><span class="keyword">set</span>(CTEST_NIGHTLY_START_TIME <span class="string">"00:00:00 EST"</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">set</span>(CTEST_DROP_METHOD <span class="string">"http"</span>)</span><br><span class="line"><span class="keyword">set</span>(CTEST_DROP_SITE <span class="string">"my.cdash.org"</span>)</span><br><span class="line"><span class="keyword">set</span>(CTEST_DROP_LOCATION <span class="string">"/submit.php?project=CMakeTutorial"</span>)</span><br><span class="line"><span class="keyword">set</span>(CTEST_DROP_SITE_CDASH <span class="keyword">TRUE</span>)</span><br></pre></td></tr></table></figure>

<h4 id="命令行使用示例-3"><a href="#命令行使用示例-3" class="headerlink" title="命令行使用示例"></a>命令行使用示例</h4><p>在项目目录下</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir build</span><br><span class="line">$ cd build</span><br><span class="line">$ cmake ..</span><br><span class="line">VS generator 注意：目录不能含有中文</span><br><span class="line">发布发行版测试结果</span><br><span class="line">$ ctest [-VV] -C Release -D Experimental</span><br><span class="line">发布调试版测试结果</span><br><span class="line">$ ctest [-VV] -C Debug -D Experimental</span><br></pre></td></tr></table></figure>


<h3 id="9-混合静态和共享库"><a href="#9-混合静态和共享库" class="headerlink" title="9. 混合静态和共享库"></a>9. 混合静态和共享库</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>在动态库中使用静态库</li>
<li>使用<code>BUILD_SHARED_LIBS</code>属性设置库默认生成类型(共享/非共享)(默认生成静态库);</li>
<li>使用目标宏定义(target_compile_definitions)设置windows动态库标志(<code>__declspec(dllexport),__declspec(dllimport)</code>)</li>
<li>在add_library中控制库生成类型[STATIC | SHARED | MODULE]</li>
</ul>
<blockquote>
<p>注: 本节示例初始代码在示例目录的<code>Step9</code>子目录, 成果在<code>Step10</code>子目录</p>
</blockquote>
<h4 id="核心代码更改-6"><a href="#核心代码更改-6" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p><strong>顶层CMakeLists.txt</strong>的起始部分更改为:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 指定CMake最小版本</span></span><br><span class="line"><span class="keyword">cmake_minimum_required</span>(VERSION <span class="number">3.10</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置项目名称及版本号</span></span><br><span class="line"><span class="keyword">project</span>(Tutorial VERSION <span class="number">1.0</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 指定C++版本</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD <span class="number">11</span>)</span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD_REQUIRED <span class="keyword">True</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 控制动静态库生成目录,这样在windows上不用考虑运行时路径问题</span></span><br><span class="line"><span class="comment"># we don't need to tinker with the path to run the executable</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_ARCHIVE_OUTPUT_DIRECTORY <span class="string">"$&#123;PROJECT_BINARY_DIR&#125;"</span>)</span><br><span class="line"><span class="keyword">set</span>(CMAKE_LIBRARY_OUTPUT_DIRECTORY <span class="string">"$&#123;PROJECT_BINARY_DIR&#125;"</span>)</span><br><span class="line"><span class="keyword">set</span>(CMAKE_RUNTIME_OUTPUT_DIRECTORY <span class="string">"$&#123;PROJECT_BINARY_DIR&#125;"</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">option</span>(BUILD_SHARED_LIBS <span class="string">"Build using shared libraries"</span> <span class="keyword">ON</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置头文件, 将一些CMake属性值保存到源代码中</span></span><br><span class="line"><span class="keyword">configure_file</span>(TutorialConfig.h.in TutorialConfig.h)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加自定义数学库</span></span><br><span class="line"><span class="keyword">add_subdirectory</span>(MathFunctions)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成执行程序</span></span><br><span class="line"><span class="keyword">add_executable</span>(Tutorial tutorial.cxx)</span><br><span class="line"><span class="keyword">target_link_libraries</span>(Tutorial PUBLIC MathFunctions)</span><br></pre></td></tr></table></figure>

<p><strong>MathFunctions/CMakeLists.txt</strong>更改如下:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 生成运行时需要的动态库</span></span><br><span class="line"><span class="keyword">add_library</span>(MathFunctions MathFunctions.cxx)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通过INTERFACE向使用者传播头文件搜索路径</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(MathFunctions</span><br><span class="line">                           INTERFACE <span class="variable">$&#123;CMAKE_CURRENT_SOURCE_DIR&#125;</span></span><br><span class="line">                           )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否使用自定义数学库</span></span><br><span class="line"><span class="keyword">option</span>(USE_MYMATH <span class="string">"Use tutorial provided math implementation"</span> <span class="keyword">ON</span>)</span><br><span class="line"><span class="keyword">if</span>(USE_MYMATH)</span><br><span class="line">  <span class="comment"># 数学库目标宏定义</span></span><br><span class="line">  <span class="keyword">target_compile_definitions</span>(MathFunctions PRIVATE <span class="string">"USE_MYMATH"</span>)</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 首先生成一个用于产生预定义值表源代码的执行程序</span></span><br><span class="line">  <span class="keyword">add_executable</span>(MakeTable MakeTable.cxx)</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 添加自定义命令以产生源代码(依赖于MakeTable目标)</span></span><br><span class="line">  <span class="keyword">add_custom_command</span>(</span><br><span class="line">    OUTPUT <span class="variable">$&#123;CMAKE_CURRENT_BINARY_DIR&#125;</span>/Table.h</span><br><span class="line">    <span class="keyword">COMMAND</span> MakeTable <span class="variable">$&#123;CMAKE_CURRENT_BINARY_DIR&#125;</span>/Table.h</span><br><span class="line">    DEPENDS MakeTable</span><br><span class="line">    )</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 生成仅进行sqrt计算的静态库</span></span><br><span class="line">  <span class="keyword">add_library</span>(SqrtLibrary STATIC</span><br><span class="line">              mysqrt.cxx</span><br><span class="line">              <span class="variable">$&#123;CMAKE_CURRENT_BINARY_DIR&#125;</span>/Table.h</span><br><span class="line">              )</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 通过PRIVATE定义目标内部使用头文件搜索路径</span></span><br><span class="line">  <span class="comment"># Table.h文件生成在$&#123;CMAKE_CURRENT_BINARY_DIR&#125;中</span></span><br><span class="line">  <span class="keyword">target_include_directories</span>(SqrtLibrary PRIVATE</span><br><span class="line">                             <span class="variable">$&#123;CMAKE_CURRENT_BINARY_DIR&#125;</span></span><br><span class="line">                             )</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 设置SqrtLibrary目标属性: 如果默认生成共享库, 需要将PIC(POSITION_INDEPENDENT_CODE)设置为True</span></span><br><span class="line">  <span class="keyword">set_target_properties</span>(SqrtLibrary PROPERTIES</span><br><span class="line">                        POSITION_INDEPENDENT_CODE <span class="variable">$&#123;BUILD_SHARED_LIBS&#125;</span></span><br><span class="line">                        )</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 将数学库链接到自定义sqrt库</span></span><br><span class="line">  <span class="keyword">target_link_libraries</span>(MathFunctions PRIVATE SqrtLibrary)</span><br><span class="line"><span class="keyword">endif</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义目标宏用于在windows上设置动态库标志declspec(dllexport)</span></span><br><span class="line"><span class="keyword">target_compile_definitions</span>(MathFunctions PRIVATE <span class="string">"EXPORTING_MYMATH"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装规则</span></span><br><span class="line"><span class="keyword">install</span>(TARGETS MathFunctions DESTINATION lib)</span><br><span class="line"><span class="keyword">install</span>(FILES MathFunctions.h DESTINATION <span class="keyword">include</span>)</span><br></pre></td></tr></table></figure>

<p><strong>MathFunctions/MathFunctions.h</strong>使用dll导出(dll export)定义:</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">if</span> defined(_WIN32)</span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">if</span> defined(EXPORTING_MYMATH)</span></span><br><span class="line"><span class="meta">#    <span class="meta-keyword">define</span> DECLSPEC __declspec(dllexport)</span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">else</span></span></span><br><span class="line"><span class="meta">#    <span class="meta-keyword">define</span> DECLSPEC __declspec(dllimport)</span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">else</span> <span class="comment">// non windows</span></span></span><br><span class="line"><span class="meta">#  <span class="meta-keyword">define</span> DECLSPEC</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> mathfunctions &#123;</span><br><span class="line"><span class="function"><span class="keyword">double</span> DECLSPEC <span class="title">sqrt</span><span class="params">(<span class="keyword">double</span> x)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>其它对C++代码的修改见<a href="https://cmake.org/cmake/help/latest/guide/tutorial/index.html" target="_blank" rel="noopener">CMake教程</a></p>
<h4 id="命令行使用示例-4"><a href="#命令行使用示例-4" class="headerlink" title="命令行使用示例"></a>命令行使用示例</h4><p>在项目目录下</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir build</span><br><span class="line">$ cd build</span><br><span class="line">$ cmake ..</span><br><span class="line">$ cmake --build .</span><br><span class="line"></span><br><span class="line">  Checking Build System</span><br><span class="line">  Building Custom Rule E:&#x2F;Help&#x2F;Other&#x2F;CMake&#x2F;CMake_Tutorial&#x2F;guide&#x2F;tutorial&#x2F;Step10&#x2F;MathFunctions&#x2F;CMakeLists.txt</span><br><span class="line">  MakeTable.cxx</span><br><span class="line">  MakeTable.vcxproj -&gt; E:\Help\Other\CMake\CMake_Tutorial\guide\tutorial\Step10\build\Debug\MakeTable.exe</span><br><span class="line">  Generating Table.h</span><br><span class="line">  Building Custom Rule E:&#x2F;Help&#x2F;Other&#x2F;CMake&#x2F;CMake_Tutorial&#x2F;guide&#x2F;tutorial&#x2F;Step10&#x2F;MathFunctions&#x2F;CMakeLists.txt</span><br><span class="line">  mysqrt.cxx</span><br><span class="line">  SqrtLibrary.vcxproj -&gt; E:\Help\Other\CMake\CMake_Tutorial\guide\tutorial\Step10\build\Debug\SqrtLibrary.lib</span><br><span class="line">  Building Custom Rule E:&#x2F;Help&#x2F;Other&#x2F;CMake&#x2F;CMake_Tutorial&#x2F;guide&#x2F;tutorial&#x2F;Step10&#x2F;MathFunctions&#x2F;CMakeLists.txt</span><br><span class="line">  MathFunctions.cxx</span><br><span class="line">    正在创建库 E:&#x2F;Help&#x2F;Other&#x2F;CMake&#x2F;CMake_Tutorial&#x2F;guide&#x2F;tutorial&#x2F;Step10&#x2F;build&#x2F;Debug&#x2F;MathFunctions.lib 和对象 E:&#x2F;Help&#x2F;Other&#x2F;CMake&#x2F;CMake_Tutorial&#x2F;guide&#x2F;tutorial&#x2F;St</span><br><span class="line">  ep10&#x2F;build&#x2F;Debug&#x2F;MathFunctions.exp</span><br><span class="line">  MathFunctions.vcxproj -&gt; E:\Help\Other\CMake\CMake_Tutorial\guide\tutorial\Step10\build\Debug\MathFunctions.dll</span><br><span class="line">  Building Custom Rule E:&#x2F;Help&#x2F;Other&#x2F;CMake&#x2F;CMake_Tutorial&#x2F;guide&#x2F;tutorial&#x2F;Step10&#x2F;CMakeLists.txt</span><br><span class="line">  tutorial.cxx</span><br><span class="line">  Tutorial.vcxproj -&gt; E:\Help\Other\CMake\CMake_Tutorial\guide\tutorial\Step10\build\Debug\Tutorial.exe</span><br><span class="line">  Building Custom Rule E:&#x2F;Help&#x2F;Other&#x2F;CMake&#x2F;CMake_Tutorial&#x2F;guide&#x2F;tutorial&#x2F;Step10&#x2F;CMakeLists.txt</span><br></pre></td></tr></table></figure>


<h3 id="10-生成器表达式-条件判断"><a href="#10-生成器表达式-条件判断" class="headerlink" title="10. 生成器表达式,条件判断"></a>10. 生成器表达式,条件判断</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>在构建过程中计算生成器表达式值，以生成特定于每个构建配置的信息</li>
<li>生成器表达式有三类: 逻辑表达式、信息表达式和输出表达式(Logical, Informational, and Output expressions)</li>
<li>逻辑表达式: <code>$&lt;0:...&gt;</code>的结果是空字符串，<code>$&lt;1:...&gt;</code>的结果是“…”的内容。它们也可以嵌套。</li>
<li>生成器表达式通常用来按需添加编译标志</li>
<li>使用<strong>INTERFACE目标</strong>在目标间传递属性</li>
</ul>
<blockquote>
<p>注: 本节示例初始代码在示例目录的<code>Step10</code>子目录, 成果在<code>Step11</code>子目录</p>
</blockquote>
<h4 id="核心代码更改-7"><a href="#核心代码更改-7" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p><strong>顶层CMakeLists.txt</strong>的相应部分:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># specify the C++ standard</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD <span class="number">11</span>)</span><br><span class="line"><span class="keyword">set</span>(CMAKE_CXX_STANDARD_REQUIRED <span class="keyword">True</span>)</span><br></pre></td></tr></table></figure>
<p>更改为:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">add_library</span>(tutorial_compiler_flags INTERFACE)</span><br><span class="line"><span class="keyword">target_compile_features</span>(tutorial_compiler_flags INTERFACE cxx_std_11)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通过BUILD_INTERFACE生成器表达式添加编译器警告标志</span></span><br><span class="line"><span class="keyword">set</span>(gcc_like_cxx <span class="string">"$&lt;COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU&gt;"</span>)</span><br><span class="line"><span class="keyword">set</span>(msvc_cxx <span class="string">"$&lt;COMPILE_LANG_AND_ID:CXX,MSVC&gt;"</span>)</span><br><span class="line"><span class="keyword">target_compile_options</span>(tutorial_compiler_flags INTERFACE</span><br><span class="line">  <span class="string">"$&lt;$&#123;gcc_like_cxx&#125;:$&lt;BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused&gt;&gt;"</span></span><br><span class="line">  <span class="string">"$&lt;$&#123;msvc_cxx&#125;:$&lt;BUILD_INTERFACE:-W3&gt;&gt;"</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure>

<p><strong>库目录CMakeLists.txt</strong>目标链接库代码:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">target_link_libraries</span>(MakeTable[SqrtLibrary|MathFunctions] PRIVATE[PUBLIC] tutorial_compiler_flags)</span><br></pre></td></tr></table></figure>

<h3 id="11-添加导出配置-以支持find-package"><a href="#11-添加导出配置-以支持find-package" class="headerlink" title="11. 添加导出配置,以支持find_package"></a>11. 添加导出配置,以支持find_package</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>如何让其他项目方便地使用本项目</li>
<li>在<strong>install(TARGETS)</strong>中使用<strong>EXPORT</strong>关键字, 它用于将目标从安装树导入到另一个项目</li>
<li>生成<strong>MathFunctionsConfig.cmake</strong>, 以让<a href="https://cmake.org/cmake/help/latest/command/find_package.html#command:find_package" target="_blank" rel="noopener">find_package()</a>命令可以找到本项目</li>
<li>显式安装生成的<strong>MathFunctionsTargets.cmake</strong></li>
</ul>
<blockquote>
<p>注: 本节示例初始代码在示例目录的<code>Step11</code>子目录, 成果在<code>Step12</code>子目录</p>
</blockquote>
<h4 id="核心代码更改-8"><a href="#核心代码更改-8" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p>在<strong>MathFunctions/CMakeLists.txt</strong>中增加<strong>EXPORT</strong>:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 根据项目内与安装方式包含不同的头文件目录</span></span><br><span class="line"><span class="keyword">target_include_directories</span>(MathFunctions</span><br><span class="line">                           INTERFACE</span><br><span class="line">                            $&lt;BUILD_INTERFACE:<span class="variable">$&#123;CMAKE_CURRENT_SOURCE_DIR&#125;</span>&gt;</span><br><span class="line">                            $&lt;INSTALL_INTERFACE:<span class="keyword">include</span>&gt;</span><br><span class="line">                           )</span><br><span class="line"></span><br><span class="line"><span class="comment"># 此处省略其他代码...</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装规则</span></span><br><span class="line"><span class="keyword">install</span>(TARGETS MathFunctions tutorial_compiler_flags</span><br><span class="line">        DESTINATION lib</span><br><span class="line">        <span class="keyword">EXPORT</span> MathFunctionsTargets)</span><br><span class="line"><span class="keyword">install</span>(FILES MathFunctions.h DESTINATION <span class="keyword">include</span>)</span><br></pre></td></tr></table></figure>

<p>在顶层目录中添加<strong>Config.cmake.in</strong>, 用来生成<strong>MathFunctionsTargets.cmake</strong>:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">@PACKAGE_INIT@</span><br><span class="line"></span><br><span class="line"><span class="keyword">include</span> ( <span class="string">"$&#123;CMAKE_CURRENT_LIST_DIR&#125;/MathFunctionsTargets.cmake"</span> )</span><br></pre></td></tr></table></figure>


<p>在<strong>顶层CMakeLists.txt</strong>，为了正确配置和安装<strong>MathFunctionsTargets.cmake</strong>, 添加以下内容:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">install</span>(<span class="keyword">EXPORT</span> MathFunctionsTargets</span><br><span class="line">  <span class="keyword">FILE</span> MathFunctionsTargets.cmake</span><br><span class="line">  DESTINATION lib/cmake/MathFunctions</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">include</span>(CMakePackageConfigHelpers)</span><br><span class="line"><span class="comment"># generate the config file that is includes the exports</span></span><br><span class="line">configure_package_config_file(<span class="variable">$&#123;CMAKE_CURRENT_SOURCE_DIR&#125;</span>/Config.cmake.in</span><br><span class="line">  <span class="string">"$&#123;CMAKE_CURRENT_BINARY_DIR&#125;/MathFunctionsConfig.cmake"</span></span><br><span class="line">  INSTALL_DESTINATION <span class="string">"lib/cmake/example"</span></span><br><span class="line">  NO_SET_AND_CHECK_MACRO</span><br><span class="line">  NO_CHECK_REQUIRED_COMPONENTS_MACRO</span><br><span class="line">  )</span><br><span class="line"><span class="comment"># generate the version file for the config file</span></span><br><span class="line">write_basic_package_version_file(</span><br><span class="line">  <span class="string">"$&#123;CMAKE_CURRENT_BINARY_DIR&#125;/MathFunctionsConfigVersion.cmake"</span></span><br><span class="line">  VERSION <span class="string">"$&#123;Tutorial_VERSION_MAJOR&#125;.$&#123;Tutorial_VERSION_MINOR&#125;"</span></span><br><span class="line">  COMPATIBILITY AnyNewerVersion</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment"># install the configuration file</span></span><br><span class="line"><span class="keyword">install</span>(FILES</span><br><span class="line">  <span class="variable">$&#123;CMAKE_CURRENT_BINARY_DIR&#125;</span>/MathFunctionsConfig.cmake</span><br><span class="line">  DESTINATION lib/cmake/MathFunctions</span><br><span class="line">  )</span><br></pre></td></tr></table></figure>

<p>到这里，这是一个可以在项目安装或打包以后重定位的CMake配置。 如果需要项目在一个构建目录中使用，在顶层<strong>CMakeLists.txt</strong>的结尾添加以下内容:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span>(<span class="keyword">EXPORT</span> MathFunctionsTargets</span><br><span class="line">  <span class="keyword">FILE</span> <span class="string">"$&#123;CMAKE_CURRENT_BINARY_DIR&#125;/MathFunctionsTargets.cmake"</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure>

<blockquote>
<p>通过这个导出调用，我们现在生成一个<code>Targets.cmake</code>，使得在构建目录中配置生成的<code>MathFunctionsConfig.cmake</code>可以被其他项目使用，而不需要安装它。<br>此处未试验, 不理解</p>
</blockquote>
<h3 id="12-将调试版和发行版打包在一起"><a href="#12-将调试版和发行版打包在一起" class="headerlink" title="12. 将调试版和发行版打包在一起"></a>12. 将调试版和发行版打包在一起</h3><p>在上一步的基础上, 本节示例展示了:</p>
<ul>
<li>为调试版文件设置后缀: 非执行程序目标会根据<strong>CMAKE_DEBUG_POSTFIX</strong>生成它的<strong><CONFIG>_POSTFIX</strong></li>
<li>执行程序目录的<strong>DEBUG_POSTFIX</strong>需要手工设置</li>
</ul>
<blockquote>
<p>注1: 本节示例初始代码在示例目录的<code>Step12</code>子目录, 成果在<code>Complete</code>子目录<br>注2: 本节打包工作在win10上没有成功</p>
</blockquote>
<h4 id="核心代码更改-9"><a href="#核心代码更改-9" class="headerlink" title="核心代码更改"></a>核心代码更改</h4><p>在<strong>顶层CMakeLists.txt</strong>中更改:</p>
<figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 设置非可执行程序目标的调试后缀</span></span><br><span class="line"><span class="keyword">set</span>(CMAKE_DEBUG_POSTFIX d)</span><br><span class="line">...</span><br><span class="line"><span class="comment"># 设置可执行程序目标的调试后缀</span></span><br><span class="line"><span class="keyword">set_target_properties</span>(Tutorial PROPERTIES DEBUG_POSTFIX <span class="variable">$&#123;CMAKE_DEBUG_POSTFIX&#125;</span>)</span><br></pre></td></tr></table></figure>



    </div>

    
    
    

      <footer class="post-footer">

        


        
    <div class="post-nav">
      <div class="post-nav-item"></div>
      <div class="post-nav-item">
    <a href="/2020/05/11/CMake%20Tutorial(v2)/" rel="next" title="CMake Tutorial(v2)">
      CMake Tutorial(v2) <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#CMake教程小结"><span class="nav-number">1.</span> <span class="nav-text">CMake教程小结</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#简介"><span class="nav-number">1.1.</span> <span class="nav-text">简介</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#主要功能摘要"><span class="nav-number">1.2.</span> <span class="nav-text">主要功能摘要</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-生成执行程序"><span class="nav-number">1.2.1.</span> <span class="nav-text">1. 生成执行程序</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码"><span class="nav-number">1.2.1.1.</span> <span class="nav-text">核心代码</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#命令行使用示例"><span class="nav-number">1.2.1.2.</span> <span class="nav-text">命令行使用示例</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-生成库-旧式CMake"><span class="nav-number">1.2.2.</span> <span class="nav-text">2. 生成库(旧式CMake)</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#生成库"><span class="nav-number">1.2.2.1.</span> <span class="nav-text">生成库</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#其它核心代码"><span class="nav-number">1.2.2.2.</span> <span class="nav-text">其它核心代码</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-生成库-新式CMake"><span class="nav-number">1.2.3.</span> <span class="nav-text">3. 生成库(新式CMake)</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改"><span class="nav-number">1.2.3.1.</span> <span class="nav-text">核心代码更改</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-基于源代码的安装与测试"><span class="nav-number">1.2.4.</span> <span class="nav-text">4. 基于源代码的安装与测试</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改-1"><span class="nav-number">1.2.4.1.</span> <span class="nav-text">核心代码更改</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#命令行使用示例-1"><span class="nav-number">1.2.4.2.</span> <span class="nav-text">命令行使用示例</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-系统检测"><span class="nav-number">1.2.5.</span> <span class="nav-text">5. 系统检测</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改-2"><span class="nav-number">1.2.5.1.</span> <span class="nav-text">核心代码更改</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-添加自定义命令以及生成文件"><span class="nav-number">1.2.6.</span> <span class="nav-text">6. 添加自定义命令以及生成文件</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改-3"><span class="nav-number">1.2.6.1.</span> <span class="nav-text">核心代码更改</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#7-构建安装程序"><span class="nav-number">1.2.7.</span> <span class="nav-text">7. 构建安装程序</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改-4"><span class="nav-number">1.2.7.1.</span> <span class="nav-text">核心代码更改</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#命令行使用示例-2"><span class="nav-number">1.2.7.2.</span> <span class="nav-text">命令行使用示例</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#8-将测试结果提交到Kitware的公共指示板"><span class="nav-number">1.2.8.</span> <span class="nav-text">8. 将测试结果提交到Kitware的公共指示板</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改-5"><span class="nav-number">1.2.8.1.</span> <span class="nav-text">核心代码更改</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#命令行使用示例-3"><span class="nav-number">1.2.8.2.</span> <span class="nav-text">命令行使用示例</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#9-混合静态和共享库"><span class="nav-number">1.2.9.</span> <span class="nav-text">9. 混合静态和共享库</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改-6"><span class="nav-number">1.2.9.1.</span> <span class="nav-text">核心代码更改</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#命令行使用示例-4"><span class="nav-number">1.2.9.2.</span> <span class="nav-text">命令行使用示例</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#10-生成器表达式-条件判断"><span class="nav-number">1.2.10.</span> <span class="nav-text">10. 生成器表达式,条件判断</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改-7"><span class="nav-number">1.2.10.1.</span> <span class="nav-text">核心代码更改</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#11-添加导出配置-以支持find-package"><span class="nav-number">1.2.11.</span> <span class="nav-text">11. 添加导出配置,以支持find_package</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改-8"><span class="nav-number">1.2.11.1.</span> <span class="nav-text">核心代码更改</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#12-将调试版和发行版打包在一起"><span class="nav-number">1.2.12.</span> <span class="nav-text">12. 将调试版和发行版打包在一起</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#核心代码更改-9"><span class="nav-number">1.2.12.1.</span> <span class="nav-text">核心代码更改</span></a></li></ol></li></ol></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">老树</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">5</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
  </nav>
</div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">老树</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://muse.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/muse.js"></script>


<script src="/js/next-boot.js"></script><!-- hexo-inject:begin --><!-- hexo-inject:end -->




  















  

  

  

</body>
</html>
